﻿
#region Usings
using System;

using PolyGameEngine.GamePieces.Common;
using PolyGameEngine.Tools;

using FarseerPhysics.Dynamics;
using FarseerPhysics.Dynamics.Contacts;

using Microsoft.Xna.Framework;

#endregion

namespace PolyGameEngine.GamePieces
{
    public abstract class EffectTile : Tile, IDisposable
    {
        public static int instances = 0;
        public static int instanceWithAccess;
        public int thisInstance;
        public bool applyEffect = false;
        public Fixture fixtureInEffect;
        public GamePiece GamePieceInEffect;

        public Material materialInEffect
        {
            get
            {
                return GamePieceInEffect.material;
            }
        }

        public Body bodyInEffect
        {
            get
            {
                return fixtureInEffect.Body;
            }
        }

        public EffectTile(PhysicsGame PhysicsGame, World World, Material Material, Vector2 Position, float Rotation, int Width, int Height, float DrawingDepth, int saveLineIndex, string GPID)
            : base(PhysicsGame, World, Material, Position,Rotation, Width, Height, DrawingDepth, saveLineIndex, GPID)
        {
            thisInstance = instances++;
        }

        
        public override void Update(GameTime gameTime)
        {


            if (applyEffect && fixtureInEffect != null)
            {
                if (requestAccess())
                {
                    Effect();
                }
                if (Vector2.Distance(position, ConvertToScreen(fixtureInEffect.Body.Position)) > 150)
                {
                    if (instanceWithAccess == thisInstance)
                        instanceWithAccess = int.MaxValue;
                    applyEffect = false;
                    GamePieceInEffect = null;
                    fixtureInEffect = null;
                }
            }
            else
            {
                if (instanceWithAccess == thisInstance)
                    instanceWithAccess = int.MaxValue;
                else
                {
                    applyEffect = false;
                    GamePieceInEffect = null;
                    fixtureInEffect = null;
                    instanceWithAccess = int.MaxValue;
                }
            }
            base.Update(gameTime);
        }
        public bool ShouldRequestAccess = true;
        public bool requestAccess()
        {
            if (ShouldRequestAccess)
            {
                if (instanceWithAccess == int.MaxValue)
                {
                    instanceWithAccess = thisInstance;
                    return true;
                }
                return false;
            }
            else
                return true;
        }

        #region Default Effect Event Handlers
        public virtual bool HandleDefaultEffect(Fixture ThisFixture, Fixture OtherFixture, Contact Contact)
        {
            fixtureInEffect = OtherFixture;
            applyEffect = true;
            GamePieceInEffect = (GamePiece)fixtureInEffect.UserData;
            return true;
        }
        public virtual void HandleDefaultAfterEffect(Fixture ThisFixture, Fixture OtherFixture)
        {
            if (instanceWithAccess == thisInstance)
                instanceWithAccess = int.MaxValue;
            applyEffect = false;
            GamePieceInEffect = null;
            fixtureInEffect = null;
        }
        #endregion
        public abstract void Effect();


        void IDisposable.Dispose()
        {
            if (thisInstance == instanceWithAccess)
                instanceWithAccess = int.MaxValue;
        }
    }
}
